#include "luaEventManager.hpp"
#include "luaEvent.hpp"

namespace lua
{

EventManager *EventManager::instance = nullptr;

EventManager::EventManager() : 
	mEvents()
{

}

EventManager* EventManager::getInstance()
{
	if(EventManager::instance == nullptr)
		instance = new EventManager;
	return EventManager::instance;
}

EventManager::~EventManager()
{
	for(std::map<const char*, std::vector<Event*>>::iterator it = mEvents.begin(); it != mEvents.end(); it++)
	{
		std::vector<Event*> &p = (*it).second;
		for(std::vector<Event*>::iterator it2 = p.begin(); it2 != p.end();)
		{
			delete *it2;
			it2 = p.erase(it2);
		}
	}
	mEvents.clear();
}

void EventManager::add(Event *event)
{
	mEvents[event->mName].push_back(event);
}

bool EventManager::remove(const char *eventName, Function callbackFunc)
{
	if(mEvents.find(eventName) != mEvents.end())
	{
		std::vector<Event*> &events = mEvents[eventName];
		for(std::vector<Event*>::iterator it = events.begin(); it != events.end(); it++)
		{
			if((*it)->mCallbackFunc == callbackFunc)
			{
				delete *it;
				events.erase(it);
				break;
			}
		}
		return true;
	}
	return false;
}

bool EventManager::trigger(const char *eventName, Args args)
{
	if(mEvents.find(eventName) != mEvents.end())
	{
		std::vector<Event*> &events = mEvents[eventName];
		std::vector<lua::Function> funcs;
		for(std::vector<Event*>::iterator it = events.begin(); it != events.end(); it++)
		{
			if((*it)->mCallbackFunc.getModule() != args.getModule())
			{
				lua::Args a((*it)->mCallbackFunc.getModule(), args);
				(*it)->mCallbackFunc(a);
			}
			else
				funcs.push_back((*it)->mCallbackFunc);
		}
		for(std::vector<lua::Function>::iterator it = funcs.begin(); it != funcs.end(); it++)
		{
			(*it)(args);
		}
		args.getModule()->clearStack();
		return true;
	}
	args.getModule()->clearStack();
	return false;
}

}